﻿

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Store.Manager.ERP.Common.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Api.Core.Filters
{
    /// <summary>
    /// 监听全局异常，处理异常
    /// </summary>
    public class Filter_GlobalException : IExceptionFilter
    {
        private readonly IWebHostEnvironment _env;
        private readonly ILogger<Filter_GlobalException> _logger;
        public Filter_GlobalException(IWebHostEnvironment env, ILogger<Filter_GlobalException> logger)
        {
            _env = env;
            _logger = logger;
        }
        public void OnException(ExceptionContext context)
        {
            //自定义返回格式
            var messageModel = new CommonResponse() { StatusCode = 500, Message = context.Exception.Message };
            context.Result = new ObjectResult(messageModel);
            //已处理
            context.ExceptionHandled = true;
            //分析请求入参
            var httpContext = context.HttpContext;
            var queryString = httpContext.Request.QueryString; // 获取查询字符串参数  
            var bodyData = httpContext.Request.Body; // 获取请求体数据
            string inputParams = "";
            if (httpContext.Request.QueryString.HasValue) { inputParams = $"{queryString}-来自query"; }
            else if (bodyData != null) { inputParams = $"{GetParamsStrFromBody(context.HttpContext)}-来自body"; }
            //写入日志
            _logger.LogError(messageModel.Message, FormatLogText(messageModel.Message, inputParams, context.Exception));
        }

        /// <summary>
        /// 格式化日志
        /// </summary>
        /// <param name="throwMsg"></param>
        /// <param name="inputParams"></param>
        /// <param name="ex"></param>
        /// <returns></returns>
        public string FormatLogText(string throwMsg, string inputParams, Exception ex)
        {
            return string.Format($"【自定义错误】：{throwMsg} \r\n【异常类型】：{ex.GetType().Name} \r\n【异常信息】：{ex.Message} \r\n【堆栈调用】：{ex.StackTrace}\r\n【请求参数】：{inputParams}");
        }

        /// <summary>
        /// 获取请求体中的参数字符串
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public async Task<string> GetParamsStrFromBody(HttpContext httpContext)
        {
            using (var reader = new System.IO.StreamReader(httpContext.Request.Body))
            {
                return await reader.ReadToEndAsync();
            }
        }
    }
}
